package org.jwd.storage.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jwd.core.entity.DataDict;
import org.jwd.core.exception.DataDictException;
import org.jwd.storage.dao.DataDictMapper;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author vizz
 * @since 2022/5/20 9:56
 * 字典放内存里
 */
@Slf4j
@Service
public class DataDictService extends ServiceImpl<DataDictMapper, DataDict> {

    /**
     * volatile保证原子性，防止多线程并发修改
     */
    private volatile List<DataDict> dataDicts = new ArrayList<>();

    /**
     * springboot启动时，需要调用一次这个初始化函数
     * 如果通过管理页面更改了字典，必须调用一次这个方法，否则更新不生效
     */
    public void initDict() {
        List<DataDict> listData = this.list();
        if (listData == null || listData.size() == 0 || listData.size() > 20000) {
            log.warn("初始化字典失败");
            return;
        } else {
            dataDicts = listData;
        }

    }

    /**
     * 找字典,不查库，直接去内存查
     */
    public String getByKeyAndCtg(String key, String ctg) {
        List<String> res = dataDicts.stream().filter(u -> {
            return key.equalsIgnoreCase(u.getDataKey());
        }).filter(u -> {
            return ctg.equalsIgnoreCase(u.getCategory());
        }).map(DataDict::getValue).collect(Collectors.toList());
        if (res.size() == 0) {
            String info = String.format("没有此字典项,key=%s,category=%s", key, ctg);
            log.warn(info);
            throw new DataDictException(info);
        } else if (res.size() > 1) {
            String info = String.format("查询到%d条字典项，但只应该有1条字典项", res.size());
            log.warn(info);
            throw new DataDictException(info);
        }
        return res.get(0);
    }

    /**
     * 找字典,不查库，直接去内存查
     * TODO：Long是对象，应该不能直接等于吧？这里equals是否可行？
     */
    public String getById(Long id) {
        List<String> res = dataDicts.stream().filter(u -> {
            return id.equals(u.getId());
        }).map(DataDict::getValue).collect(Collectors.toList());
        if (res.size() == 0) {
            String info = String.format("没有此字典项,id=%d", id);
            log.warn(info);
            throw new DataDictException(info);
        } else if (res.size() > 1) {
            String info = String.format("查询到%d条字典项，但只应该有1条字典项", res.size());
            log.warn(info);
            throw new DataDictException(info);
        }
        return res.get(0);
    }

}
